<?php
/**
 *
 * Mongodb 业务操作基类
 *
 * MongoDbBase.class.php
 * Created by IntelliJ IDEA.
 *
 * @author: hjh <hjh@jf.com>
 *
 * Date: 2017/8/31
 * Time: 17:18
 */

namespace Common;

class MongoDbBase
{
    private $conn = null;
    private $db = null;
    private $colection = null;

    protected $mongo = null;
    protected static $mongoHost = Bridge::MONGODB_DEFAULT;

    public function __construct($db, $collection)
    {
        $this->db = $db;
        $this->colection = $collection;
        $this->conn = Bridge::mongodb(static::$mongoHost);
        $this->mongo = $this->conn->selectCollection($db, $collection);
    }

    public function createIndex($key, $options = [])
    {
        try {
            $this->mongo->createIndex($key, $options);
        } catch (\Exception $exception) {
            debug_log($key);
            debug_log($exception, JF_LOG_ERROR);
        }
    }

    /**
     * 获取总数量
     *
     * @param array $filter
     * @param array $options
     * @return int
     */
    public function total($filter, $options = [])
    {
        try {
            $ret = $this->mongo->count($filter, $options);
        } catch (\Exception $exception) {
            debug_log($exception, JF_LOG_ERROR);
            $ret = 0;
        }

        return $ret;
    }

    /**
     * 获取单个数据
     *
     * @param       $filter
     * @param array $options
     * @return array|bool|null|object
     */
    public function findOne($filter, $options = [])
    {
        try {
            $ret = $this->mongo->findOne($filter, $options);
        } catch (\Exception $exception) {
            debug_log($exception, JF_LOG_ERROR);
            $ret = false;
        }
        if ($ret === null) {
            $ret = false;
        }

        return $ret;
    }

    /**
     * 查找内容
     *
     * @param       $filter
     * @param array $options
     * @return array|bool
     */
    public function find($filter, $options = [])
    {
        try {
            $list = $this->mongo->find($filter, $options);
        } catch (\Exception $exception) {
            debug_log($exception, JF_LOG_ERROR);

            return false;
        }

        return $list->toArray();
    }

    /**
     * 删除
     *
     * @param $filter
     * @param $options
     * @return bool
     */
    public function delete($filter, $options = [])
    {
        try {
            $ret = $this->mongo->deleteMany($filter, $options);
        } catch (\Exception $exception) {
            debug_log($exception, JF_LOG_ERROR);

            return false;
        }
        if (!$ret->isAcknowledged()) {
            return false;
        }

        return true;
    }

    /**
     * 删除单个
     *
     * @param       $filter
     * @param array $options
     * @return bool
     */
    public function deleteOne($filter, $options = [])
    {
        try {
            $ret = $this->mongo->deleteOne($filter, $options);
        } catch (\Exception $exception) {
            debug_log($exception, JF_LOG_ERROR);

            return false;
        }
        if (!$ret->isAcknowledged()) {
            return false;
        }

        return true;
    }

    /**
     * 插入一条数据
     *
     * @param       $document
     * @param array $options
     * @return bool|mixed
     */
    public function insertOne($document, $options = [])
    {
        try {
            $ret = $this->mongo->insertOne($document, $options);
        } catch (\Exception $exception) {
            debug_log($exception, JF_LOG_ERROR);

            return false;
        }
        if (!$ret->isAcknowledged()) {
            return false;
        }

        return $ret->getInsertedId();
    }

    /**
     * 更新一条记录
     *
     * @param       $filter
     * @param       $updates
     * @param array $options
     * @return bool
     */
    public function updateOne($filter, $updates, $options = [])
    {
        try {
            $ret = $this->mongo->updateOne($filter, $updates, $options);
        } catch (\Exception $exception) {
            debug_log($exception, JF_LOG_ERROR);

            return false;
        }
        if (!$ret->isAcknowledged()) {
            return false;
        }

        return true;
    }

    /**
     * 更新多条
     *
     * @param       $filter
     * @param       $updates
     * @param array $options
     * @return bool
     */
    public function updateMany($filter, $updates, $options = [])
    {
        try {
            $ret = $this->mongo->updateMany($filter, $updates, $options);
        } catch (\Exception $exception) {
            debug_log($exception, JF_LOG_ERROR);

            return false;
        }
        if (!$ret->isAcknowledged()) {
            return false;
        }

        return true;
    }

    /**
     * @param       $pipeline
     * @param array $options
     * @return bool|\ArrayIterator
     */
    public function aggregation($pipeline, $options = [])
    {
        try {
            $ret = $this->mongo->aggregate($pipeline, $options);
        } catch (\Exception $exception) {
            debug_log($exception, JF_LOG_ERROR);

            return false;
        }

        return $ret;
    }

    /**
     * @param array $options
     * @return \MongoDB\Model\IndexInfoIterator
     */
    public function getIndexes($options = [])
    {
        return $this->mongo->listIndexes($options);
    }

    public function removeIndexes($indexName = null, $options = [])
    {
        if ($indexName == null) {
            $this->mongo->dropIndexes($options = []);
        } else {
            $this->mongo->dropIndex($indexName, $options);
        }
    }

    public function getDataBases($options = [])
    {
        return $this->conn->listDatabases($options);
    }

    public function removeDataBase($options = [])
    {
        $this->conn->dropDatabase($this->db, $options);
    }

    public function selectDatabase($db, $options = [])
    {
        return $this->conn->selectDatabase($db, $options);
    }

    public function createCollection($db, $collection)
    {
        return $this->selectDatabase($db)->createCollection($collection);
    }

    public function deleteCollection($db, $collection)
    {
        return $this->selectDatabase($db)->dropCollection($collection);
    }

    public function getCollections($db, $options = [])
    {
        return $this->selectDatabase($db)->listCollections($options);
    }
}
